using Infrastructure.Attribute;
using Infrastructure.Extensions;
using JTZY.Model.Product.Dto;
using JTZY.Model.Product;
using JTZY.Repository;
using JTZY.Service.Product.IProductService;
using JTZY.Model.Order;
using JTZY.Model.Goods;
using JTZY.Model.Brand;
using JTZY.Model.Business;
using static System.Net.Mime.MediaTypeNames;

namespace JTZY.Service.Product
{
    /// <summary>
    /// 货物表Service业务层处理
    /// </summary>
    [AppService(ServiceType = typeof(IProdinfoService), ServiceLifetime = LifeTime.Transient)]
    public class ProdinfoService : BaseService<Prodinfo>, IProdinfoService
    {
        /// <summary>
        /// 查询货物表列表
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        public PagedInfo<ProdinfoDto> GetList(ProdinfoQueryDto parm)
        {
            var predicate = QueryExp(parm);
            if (parm.Type.HasValue && parm.Type == 2)
            {
                var response = Queryable()
                    .Where(predicate.ToExpression())
                    .LeftJoin<Corecmsproducts>((it, prod) => prod.Id == it.ProductId)
                    .WhereIF(!string.IsNullOrEmpty(parm.Sn), (it, prod) => it.SnCode == parm.Sn || prod.Barcode == parm.Sn)
                    .LeftJoin<Corecmsgoods>((it, prod, goods) => goods.Id == prod.GoodsId)
                    .LeftJoin<Corecmsbrand>((it, prod, goods, brand) => goods.BrandId == brand.Id)
                    .LeftJoin<Corecmsuser>((it, prod, goods, brand, user) => it.UserCusId == user.Id)
                    .Select((it, prod, goods, brand, user) => new ProdinfoDto
                    {
                        SnCode = it.SnCode,
                        ProdctDate = it.ProdctDate,
                        UserId = it.UserId,
                        UserCusId = it.UserCusId,
                        QrCode = it.QrCode,
                        BarCode = prod.Barcode,
                        BrandName = brand.Name,
                        SkuName = prod.SpesDesc,
                        SkuImage = goods.Image,
                        CusUserName = user.UserName,
                    })
                    .ToPage<ProdinfoDto>(parm);

                var ext = Queryable().Where(predicate.ToExpression()).Select(it => new
                {
                    Nums = SqlFunc.AggregateCount(it.SnCode),
                    Amount = SqlFunc.AggregateSum(it.CostPrice)

                }).First();

                response.Extra = new Dictionary<string, object>()
            {
                { "CateNums",1 },
                { "Nums",ext.Nums },
                { "Amount",ext.Amount }
            };

                return response;
            }
            else 
            {
                var response = Queryable()
                .Where(predicate.ToExpression())
                .LeftJoin<Corecmsproducts>((it, prod) => prod.Id == it.ProductId)
                .WhereIF(!string.IsNullOrEmpty(parm.Sn), (it, prod) => it.SnCode == parm.Sn || prod.Barcode == parm.Sn)
                .LeftJoin<Corecmsgoods>((it, prod, goods) => goods.Id == prod.GoodsId)
                .LeftJoin<Corecmsbrand>((it, prod, goods, brand) => goods.BrandId == brand.Id)
                .Select((it, prod, goods, brand) => new ProdinfoDto
                {
                    SnCode = it.SnCode,
                    ProdctDate = it.ProdctDate,
                    UserId = it.UserId,
                    UserCusId = it.UserCusId,
                    QrCode = it.QrCode,
                    BarCode = prod.Barcode,
                    BrandName = brand.Name,
                    SkuName = prod.SpesDesc,
                    SkuImage = goods.Image,
                    Sn=prod.Sn,
                    InboundTime = it.InboundTime,
                })
                .ToPage<ProdinfoDto>(parm);

                var ext = Queryable().Where(predicate.ToExpression()).Select(it => new
                {
                    Nums = SqlFunc.AggregateCount(it.SnCode),
                    Amount = SqlFunc.AggregateSum(it.CostPrice)

                }).First();

                response.Extra = new Dictionary<string, object>()
            {
                { "CateNums",1 },
                { "Nums",ext.Nums },
                { "Amount",ext.Amount }
            };

                return response;
            }
        }


        /// <summary>
        /// 获取详情
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public Prodinfo GetInfo(long Id)
        {
            var response = Queryable()
                .Where(x => x.Id == Id)
                .First();

            return response;
        }

        /// <summary>
        /// 获取一物一码
        /// </summary>
        /// <param name="snCode"></param>
        /// <returns></returns>
        public Prodinfo GetProdinfoByCode(string snCode,string f="")
        {
            var response = f=="w"? Queryable()
                .Where(x => x.SnCode == snCode)
                .First() : Queryable()
                .Where(x => x.NCode == snCode)
                .First();

            return response;
        }

        public Prodinfo GetProdinfoByNCode(string snCode)
        {
            var response = Queryable()
                .Where(x => x.NCode == snCode)
                .First();

            return response;
        }

        /// <summary>
        /// 添加货物表
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public Prodinfo AddProdinfo(Prodinfo model)
        {
            return Insertable(model).ExecuteReturnEntity();
        }

        /// <summary>
        /// 修改货物表
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public int UpdateProdinfo(Prodinfo model)
        {
            return Update(model, true);
        }

        public List<ProdDto> GetDetail(string orderId) 
        {

            return Context.Queryable<Orderdetail>()
                .LeftJoin<Prodinfo>((o, p) => o.SnCode == p.SnCode)
                .LeftJoin<Corecmsproducts>((o, p,cp)=>o.ProductId==cp.Id)
                .Where((o, p, cp) => o.OrderId == orderId)
                .Select((o, p, cp) =>new ProdDto
                { 
                    SnCode=o.SnCode,
                    ProductId=o.ProductId,
                    SkuName=cp.SpesDesc,
                    BrandName="",
                    ProdctDate=p.ProdctDate,
                    imageurl=cp.Images,
                }).ToList();


        }

        public List<ProdDto> GetAfterDetail(string afterId) 
        {
            return Context.Queryable<Billaftersaledetail>()
    .LeftJoin<Prodinfo>((o, p) => o.SnCode == p.SnCode)
    .LeftJoin<Corecmsproducts>((o, p, cp) => o.ProductId == cp.Id)
    .Where((o, p, cp) => o.AftersalesId == afterId)
    .Select((o, p, cp) => new ProdDto
    {
        SnCode = o.SnCode,
        ProductId = o.ProductId,
        SkuName = cp.SpesDesc,
        BrandName = "",
        ProdctDate = p.ProdctDate,
        imageurl = cp.Images,
    }).ToList();
        }

        /// <summary>
        /// 查询导出表达式
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        private static Expressionable<Prodinfo> QueryExp(ProdinfoQueryDto parm)
        {

            var predicate = Expressionable.Create<Prodinfo>();
            predicate = predicate.And(it=>it.UserId==parm.UserId&&it.IsReturn==0&&it.Status==1);
            predicate= predicate.AndIF(parm.Type.HasValue&& parm.Type==2, it => it.UserCusId >0);
            predicate = predicate.AndIF(parm.Type.HasValue && parm.Type == 1, it => it.UserCusId == 0 || it.UserCusId==null);
            predicate = predicate.AndIF(parm.productId.HasValue, it => it.ProductId == parm.productId);
            predicate = predicate.AndIF(parm.userCusId.HasValue, it => it.UserCusId == parm.userCusId);
            if (!string.IsNullOrEmpty(parm.InboundTime))
            {
                DateTime dt = Convert.ToDateTime(parm.InboundTime);
                predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.InboundTime), it => it.InboundTime >= dt && it.InboundTime < dt.AddDays(1));

            }
            return predicate;
        }
    }
}